package com.ftcs.controller;

import cn.hutool.core.date.DateUtil;
import com.ftcs.controller.common.request.FinishedTasksRequest;
import com.ftcs.controller.common.request.InvovedProcessInstanceRequest;
import com.ftcs.controller.common.request.Submit2NextRequest;
import com.ftcs.controller.common.request.TodoTasksRequest;
import com.ftcs.controller.common.service.ActivitiService;
import com.ftcs.entity.PurchaseApply;
import com.ftcs.model.*;
import com.ftcs.model.historyinstance.PurchaseHistoryProcess;
import com.ftcs.service.PurchaseService;
import com.ftcs.service.SystemService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(value = "采购流程接口")
@Slf4j
@Controller
public class PurchaseController {
    @Autowired
    RepositoryService repositoryservice;
    @Autowired
    RuntimeService runservice;
    @Autowired
    TaskService taskservice;
    @Autowired
    HistoryService histiryservice;
    @Autowired
    SystemService systemservice;
    @Autowired
    PurchaseService purchaseservice;
    @Autowired
    private ActivitiService activitiService;

    @GetMapping(value = "/purchase")
    String purchase() {
        return "purchase/purchaseapply";
    }

    @GetMapping(value = "/historypurchaseprocess")
    String historypurchaseprocess() {
        return "purchase/historypurchaseprocess";
    }

    @GetMapping(value = "/purchasemanager")
    String purchasemanager() {
        return "purchase/purchasemanager";
    }

    @GetMapping(value = "/finance")
    String finance() {
        return "purchase/finance";
    }

    @GetMapping(value = "/manager")
    String manager() {
        return "purchase/manager";
    }

    @GetMapping(value = "/pay")
    String pay() {
        return "purchase/pay";
    }

    @GetMapping(value = "/updateapply")
    String updateapply() {
        return "purchase/updateapply";
    }

    @GetMapping(value = "/receiveitem")
    String receiveitem() {
        return "purchase/receiveitem";
    }


    @GetMapping(value = "/mypurchase")
    String mypurchase() {
        return "purchase/mypurchase";
    }

    @PostMapping(value = "startpurchase")
    @ResponseBody
    public Msg startpurchase(@RequestParam("itemlist") String itemlist, @RequestParam("total") BigDecimal total, HttpSession session) {
        String userid = (String) session.getAttribute("username");
        Map<String, Object> variables = new HashMap<>();
        variables.put("starter", userid);
        PurchaseApply purchase = PurchaseApply.builder().applyer(userid).itemlist(itemlist).total(total).applytime(DateUtil.date()).build();
        ProcessInstance ins = purchaseservice.startWorkflow(purchase, userid, "purchase", variables);
        log.info("流程id" + ins.getId() + "已启动");
        return new Msg("success");
    }

    /**
     * 我发起的采购流程
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "mypurchaseprocess")
    @ResponseBody
    public PageData<RunningProcess> mypurchaseprocess(HttpSession session, @RequestParam("current") int current,
                                                      @RequestParam("rowCount") int pageSize) {
        String userId = (String) session.getAttribute("username");
        int firstrow = (current - 1) * pageSize;
        ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
        int total = (int) query.count();

        InvovedProcessInstanceRequest request = InvovedProcessInstanceRequest.builder()
                .userId(userId)
                .processDefKey("purchase")
                .firstRow(firstrow).pageSize(pageSize).build();
        List<RunningProcess> list = activitiService.listInvolvingProcessInstances(request);

        List<RunningProcess> resultList = list.stream().filter(instance -> {
            PurchaseApply apply = purchaseservice.getPurchase(Integer.parseInt(instance.getBusinessKey()));
            return apply.getApplyer().equals(userId);
        }).collect(Collectors.toList());

        PageData<RunningProcess> grid = new PageData<>(current, pageSize);
        grid.setTotal(total);
        grid.setRows(resultList);
        return grid;
    }


    /**
     * 采购经理待办任务列表
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "/puchasemanagertasklist")
    @ResponseBody
    PageData<PurchaseTask> puchasemanagertasklist(HttpSession session, @RequestParam("current") int current,
                                                  @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize, 0, new ArrayList<>());
        // 先做权限检查，对于没有采购经理角色的用户,直接返回空
        String username = (String) session.getAttribute("username");
        boolean flag = systemservice.validateRole(username, "采购经理");
        // 有权限
        if (flag) {
            TodoTasksRequest request = TodoTasksRequest.builder().current(current).pageSize(pageSize).userGroup("采购经理").build();
            PurchaseTaskDTO results = purchaseservice.listTodoTasks(request);

            List<PurchaseTask> tasks = transTaskList(results.getTaskList());
            grid.setTotal(results.getPageInfo().getTotal());
            grid.setRows(tasks);
        }
        return grid;
    }


    /**
     * 财务管理员待办任务
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "/financetasklist")
    @ResponseBody
    PageData<PurchaseTask> financetasklist(HttpSession session, @RequestParam("current") int current,
                                           @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize, 0, new ArrayList<>());
        // 先做权限检查，对于没有财务管理员角色的用户,直接返回空
        String username = (String) session.getAttribute("username");
        boolean flag = systemservice.validateRole(username, "财务管理员");
        // 有权限
        if (flag) {
            TodoTasksRequest request = TodoTasksRequest.builder().current(current).pageSize(pageSize).userGroup("财务管理员").build();
            PurchaseTaskDTO results = purchaseservice.listTodoTasks(request);

            List<PurchaseTask> tasks = transTaskList(results.getTaskList());
            grid.setTotal(results.getPageInfo().getTotal());
            grid.setRows(tasks);
        }
        return grid;
    }

    /**
     * 总经理待办任务列表
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "/managertasklist")
    @ResponseBody
    PageData<PurchaseTask> managertasklist(HttpSession session, @RequestParam("current") int current,
                                           @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize, 0, new ArrayList<>());
        // 先做权限检查，对于没有总经理角色的用户,直接返回空
        String username = (String) session.getAttribute("username");
        boolean flag = systemservice.validateRole(username, "总经理");
        // 有权限
        if (flag) {
            TodoTasksRequest request = TodoTasksRequest.builder().current(current).pageSize(pageSize).userGroup("总经理").build();
            PurchaseTaskDTO results = purchaseservice.listTodoTasks(request);

            List<PurchaseTask> tasks = transTaskList(results.getTaskList());
            grid.setTotal(results.getPageInfo().getTotal());
            grid.setRows(tasks);
        }
        return grid;
    }

    /**
     * 出纳员任务列表
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "/paytasklist")
    @ResponseBody
    PageData<PurchaseTask> paytasklist(HttpSession session, @RequestParam("current") int current,
                                       @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize, 0, new ArrayList<>());
        // 先做权限检查，对于没有出纳角色的用户,直接返回空
        String username = (String) session.getAttribute("username");
        boolean flag = systemservice.validateRole(username, "出纳员");
        // 有权限
        if (flag) {
            TodoTasksRequest request = TodoTasksRequest.builder().current(current).pageSize(pageSize).userGroup("出纳员").build();
            PurchaseTaskDTO results = purchaseservice.listTodoTasks(request);

            List<PurchaseTask> tasks = transTaskList(results.getTaskList());
            grid.setTotal(results.getPageInfo().getTotal());
            grid.setRows(tasks);
        }
        return grid;
    }


    /**
     * 收货确认
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "/receivetasklist")
    @ResponseBody
    PageData<PurchaseTask> receivetasklist(HttpSession session, @RequestParam("current") int current,
                                           @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize);
        String userid = (String) session.getAttribute("username");

        TodoTasksRequest request = TodoTasksRequest.builder().current(current).pageSize(pageSize).taskName("收货确认").userId(userid).build();
        PurchaseTaskDTO results = purchaseservice.listTodoTasks(request);

        List<PurchaseTask> taskList = transTaskList(results.getTaskList());
        grid.setTotal(results.getPageInfo().getTotal());
        grid.setRows(taskList);
        return grid;
    }


    /**
     * 任务转换为采购业务对象
     *
     * @param tasks
     * @return
     */
    private List<PurchaseTask> transTaskList(List<Task> tasks) {
        return tasks.stream().map(task -> {
            PurchaseTask purchaseTask = new PurchaseTask();
            String businessKeyId = activitiService.getBusinessKeyByTaskId(task.getId());
            PurchaseApply purchaseApply = purchaseservice.getPurchase(Integer.parseInt(businessKeyId));
            purchaseTask.setApplyer(purchaseApply.getApplyer());
            purchaseTask.setApplytime(DateUtil.format(purchaseApply.getApplytime(), "yyyy-MM-dd HH:mm:ss"));
            purchaseTask.setBussinesskey(purchaseApply.getId());
            purchaseTask.setItemlist(purchaseApply.getItemlist());
            purchaseTask.setProcessdefid(task.getProcessDefinitionId());
            purchaseTask.setProcessinstanceid(task.getProcessInstanceId());
            purchaseTask.setTaskid(task.getId());
            purchaseTask.setTaskname(task.getName());
            purchaseTask.setTotal(purchaseApply.getTotal());
            return purchaseTask;
        }).collect(Collectors.toList());
    }

    @PostMapping(value = "task/purchasemanagercomplete/{taskid}")
    @ResponseBody
    public Msg purchasemanagercomplete(HttpSession session, @PathVariable("taskid") String taskid,
                                       HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");

        String purchaseauditi = req.getParameter("purchaseauditi");
        Map<String, Object> variables = new HashMap<>();
        variables.put("purchaseauditi", purchaseauditi);

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).variables(variables).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }

    @PostMapping(value = "task/updateapplycomplete/{taskid}")
    @ResponseBody
    public Msg adjustApplyComplete(HttpSession session, @PathVariable("taskid") String taskid, HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");
        //是否重新申请，如果是，更新申请信息
        String updateapply = req.getParameter("updateapply");
        if (updateapply.equals("true")) {
            String itemlist = req.getParameter("itemlist");
            String total = req.getParameter("total");
            String businessKey = activitiService.getBusinessKeyByTaskId(taskid);
            PurchaseApply p = purchaseservice.getPurchase(Integer.parseInt(businessKey));
            p.setItemlist(itemlist);
            p.setTotal(new BigDecimal(Integer.parseInt(total)));
            purchaseservice.updatePurchase(p);
        }
        Map<String, Object> variables = new HashMap();
        variables.put("updateapply", Boolean.parseBoolean(updateapply));

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).comment("重新申请了一份而已").variables(variables).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }


    @PostMapping(value = "task/managercomplete/{taskid}")
    @ResponseBody
    public Msg managercomplete(HttpSession session,
                               @PathVariable("taskid") String taskid, HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");
        //总经理是否通过
        Map<String, Object> variables = new HashMap<>();
        String manager = req.getParameter("manager");
        variables.put("manager", manager);

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).variables(variables).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }

    @PostMapping(value = "task/financecomplete/{taskid}")
    @ResponseBody
    public Msg financecomplete(HttpSession session, @RequestParam("total") String total,
                               @PathVariable("taskid") String taskid, HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");

        //两个单向网关，判断财务审批是否通过，金额是否大于1万
        String finance = req.getParameter("finance");
        Map<String, Object> variables = new HashMap<>();
        variables.put("finance", finance);
        if (finance.equals("true")) {
            variables.put("money", total);
        }

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).variables(variables).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }


    @PostMapping(value = "task/paycomplete/{taskid}")
    @ResponseBody
    public Msg paycomplete(HttpSession session, @PathVariable("taskid") String taskid, HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }

    /**
     * 收货
     *
     * @param session
     * @param taskid
     * @param req
     * @return
     */
    @PostMapping(value = "task/receivecomplete/{taskid}")
    @ResponseBody
    public Msg receivecomplete(HttpSession session, @PathVariable("taskid") String taskid, HttpServletRequest req) {
        String userid = (String) session.getAttribute("username");

        Submit2NextRequest request = Submit2NextRequest.builder().taskId(taskid).userId(userid).build();
        activitiService.submitTask(request);
        return new Msg("ok");
    }


    @PostMapping(value = "updatepurchaseapply")
    @ResponseBody
    public PageData<PurchaseTask> adjustPurchaseApply(HttpSession session, @RequestParam("current") int current,
                                                      @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseTask> grid = new PageData<>(current, pageSize);
        int firstrow = (current - 1) * pageSize;
        String userId = (String) session.getAttribute("username");
        TaskQuery query = taskservice.createTaskQuery()
                .processDefinitionKey("purchase")
                .taskCandidateOrAssigned(userId)
                .taskDefinitionKey("updateapply");
        long total = query.count();
        List<Task> tasks = query.listPage(firstrow, pageSize);
        List<PurchaseTask> purchaseTaskList = transTaskList(tasks);

        grid.setTotal((int) total);
        grid.setRows(purchaseTaskList);
        return grid;
    }

    /**
     * 我的流程实例历史
     *
     * @param session
     * @param current
     * @param pageSize
     * @return
     */
    @PostMapping(value = "getfinishpurchaseprocess")
    @ResponseBody
    public PageData<PurchaseHistoryProcess> getHistory(HttpSession session, @RequestParam("current") int current,
                                               @RequestParam("rowCount") int pageSize) {
        PageData<PurchaseHistoryProcess> grid = new PageData<>(current, pageSize);
        String userid = (String) session.getAttribute("username");

        FinishedTasksRequest request = FinishedTasksRequest.builder().proDefKey("purchase").userId(userid).current(current).pageSize(pageSize).build();
        FinishedInstanceDTO finishedInstanceDTO = activitiService.listFinishedProcessInstances(request);

        List<PurchaseHistoryProcess> list = finishedInstanceDTO.getInstanceList().stream().map(history -> {
            PurchaseHistoryProcess his = new PurchaseHistoryProcess();
            String bussinesskey = history.getBusinessKey();

            PurchaseApply apply = purchaseservice.getPurchase(Integer.parseInt(bussinesskey));
            his.setPurchaseapply(apply);
            his.setBusinessKey(bussinesskey);
            his.setProcessDefinitionId(history.getProcessDefinitionId());
            return his;
        }).collect(Collectors.toList());

        grid.setTotal(finishedInstanceDTO.getPageInfo().getTotal());
        grid.setRows(list);
        return grid;
    }

    @PostMapping(value = "/processhis")
    @ResponseBody
    public List<HistoricActivityInstance> processhis(@RequestParam("instanceId") String instanceId) {
        List<HistoricActivityInstance> his = histiryservice.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .orderByHistoricActivityInstanceStartTime()
                .asc().list();
        return his;
    }

}
